<template>
  <div class="experiment-form">
    <!-- 表单标题 -->
    <div class="form-title">
      {{ projectParamConfig.projectName }}（执行标准：{{ projectParamConfig.standardCode }}）
    </div>

    <!-- ElementUI 表单 -->
    <el-form 
      ref="experimentForm" 
      :model="formData" 
      :rules="formRules" 
      label-width="180px"
      class="main-form"
    >
      <!-- 循环渲染所有参数组 -->
      <div v-for="group in projectParamConfig.paramGroups" :key="group.groupId" class="param-group">
        <!-- 参数组标题 -->
        <div class="group-title">
          <span class="title-icon"></span>
          {{ group.groupName }}
        </div>

        <!-- 非嵌套组：表格型/单值型 -->
        <div class="normal-group">
          <!-- 表格型（动态增删试件） -->
          <el-table 
            v-if="group.allowDynamicRows" 
            :data="formData[`group_${group.groupId}`]" 
            border 
            stripe 
            class="dynamic-table"
            :max-height="400"
            size="mini"
          >
            <!-- 循环渲染表格列 -->
            <el-table-column 
              v-for="param in group.paramItems" 
              :key="param.paramId" 
              :label="getParamLabel(param)"
              :width="param.columnWidth || ''"
              align="center"
            >
              <template #default="scope">
                <!-- 多次测量参数：自定义组件 -->
                <multi-measure-input
                  v-if="param.isMultiMeasure"
                  :multiMeasureCount="param.multiMeasureCount || 1"
                  v-model="scope.row[param.paramCode]"
                  :precision="param.precision || 1"
                  size="mini"
                  @change="() => handleParamChange(param, scope.$index, group.groupId)"
                />
                <!-- 计算参数：普通输入框（不可编辑，placeholder显示自动计算） -->
                <el-input
                  v-else-if="param.paramType === 'calculation'"
                  v-model="scope.row[param.paramCode]"
                  disabled
                  size="mini"
                  :placeholder="param.placeholder || '自动计算'"
                />
                <!-- 数字类型参数：el-input type="number" -->
                <el-input
                  v-else-if="param.dataType === 'number'"
                  v-model.number="scope.row[param.paramCode]"
                  type="number"
                  :placeholder="param.isRequired ? '必填（数字）' : '选填（数字）'"
                  size="mini"
                  inputmode="decimal"
                  pattern="\d+(\.\d+)?"
                  @blur="(e) => handleNumberBlur(e, param, scope.row, scope.$index, group.groupId)"
                  @change="() => handleParamChange(param, scope.$index, group.groupId)"
                />
                <!-- 其他类型参数：动态组件 -->
                <component
                  v-else
                  :is="getElComponent(param)"
                  v-model="scope.row[param.paramCode]"
                  v-bind="getComponentProps(param)"
                  size="mini"
                  @change="() => handleParamChange(param, scope.$index, group.groupId)"
                >
                  <template v-if="param.dataType === 'select' && param.options">
                    <el-option 
                      v-for="opt in param.options" 
                      :key="opt.value" 
                      :label="opt.label" 
                      :value="opt.value"
                    ></el-option>
                  </template>
                </component>
              </template>
            </el-table-column>

            <!-- 操作列：删除试件 -->
            <el-table-column label="操作" width="80" align="center">
              <template #default="scope">
                <el-button 
                  type="text" 
                  icon="el-icon-delete" 
                  size="mini"
                  @click="deleteTableRow(group.groupId, scope.$index)"
                  :disabled="formData[`group_${group.groupId}`].length <= 1"
                  class="delete-row-btn"
                ></el-button>
              </template>
            </el-table-column>
          </el-table>

          <!-- 添加试件按钮 -->
          <el-button 
            v-if="group.allowDynamicRows"
            type="text" 
            icon="el-icon-plus" 
            size="mini"
            @click="addTableRow(group.groupId)"
            :disabled="formData[`group_${group.groupId}`].length >= group.maxRows"
            class="add-row-btn"
          >
            添加试件（当前{{ formData[`group_${group.groupId}`].length }}/{{ group.maxRows }}个）
          </el-button>

          <!-- 单值型（基础信息/汇总） -->
          <div v-else class="single-value-group">
            <el-row :gutter="20">
              <el-col 
                v-for="param in group.paramItems" 
                :key="param.paramId" 
                :span="param.dataType === 'textarea' ? 24 : 8"
                class="form-item-col"
              >
                <el-form-item :label="getParamLabel(param)" :required="param.isRequired">
                  <!-- 数字类型参数：el-input type="number" -->
                  <el-input
                    v-if="param.dataType === 'number' && !param.isMultiMeasure"
                    v-model.number="formData[param.paramCode]"
                    type="number"
                    :placeholder="param.isRequired ? '必填（数字）' : '选填（数字）'"
                    size="mini"
                    inputmode="decimal"
                    pattern="\d+(\.\d+)?"
                    @blur="(e) => handleNumberBlur(e, param, formData)"
                    @change="() => handleParamChange(param)"
                  />
                  <!-- 多次测量参数：自定义组件 -->
                  <multi-measure-input
                    v-else-if="param.isMultiMeasure"
                    :multiMeasureCount="param.multiMeasureCount || 1"
                    v-model="formData[param.paramCode]"
                    :precision="param.precision || 1"
                    size="mini"
                    @change="() => handleParamChange(param)"
                  />
                  <!-- 计算参数：普通输入框（不可编辑，placeholder显示自动计算） -->
                  <el-input
                    v-else-if="param.paramType === 'calculation'"
                    v-model="formData[param.paramCode]"
                    disabled
                    size="mini"
                    :placeholder="param.placeholder || '自动计算'"
                  />
                  <!-- 其他类型参数：动态组件 -->
                  <component
                    v-else
                    :is="getElComponent(param)"
                    v-model="formData[param.paramCode]"
                    v-bind="getComponentProps(param)"
                    :disabled="param.paramType === 'calculation'"
                    @change="() => handleParamChange(param)"
                    size="mini"
                  >
                    <template v-if="param.dataType === 'select' && param.options">
                      <el-option 
                        v-for="opt in param.options" 
                        :key="opt.value" 
                        :label="opt.label" 
                        :value="opt.value"
                      ></el-option>
                    </template>
                  </component>
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </div>
      </div>

      <!-- 表单操作按钮 -->
      <div class="form-actions">
        <el-button type="primary" @click="submitForm">提交试验数据</el-button>
        <el-button @click="resetForm">重置表单</el-button>
        <el-button type="text" @click="$emit('cancel')" v-if="showCancelBtn">取消</el-button>
      </div>
    </el-form>
  </div>
</template>

<script>
import MultiMeasureInput from './MultiMeasureInput.vue';
import { calcParamValue } from '@/utils/calcEngine';

export default {
  name: 'ExperimentForm',
  components: { MultiMeasureInput },
  props: {
    projectParamConfig: {
      type: Object,
      required: true,
      default: () => ({ paramGroups: [] })
    },
    showCancelBtn: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      formData: {}, // 表单数据：{ group_组ID: 试件数组, 参数编码: 值 }
      formRules: {}, // 表单校验规则
      paramMap: {}, // 所有参数的映射：paramId → param（优化查询）
      reverseDependencyMap: {} // 反向依赖映射：依赖的paramId → 所有依赖它的计算参数（核心）
    };
  },
  mounted() {
    this.initParamMap(); // 初始化参数映射
    this.initFormData();
    this.initFormRules();
    this.initReverseDependencyMap(); // 初始化反向依赖映射
  },
  methods: {
    // 1. 初始化参数映射（优化参数查询性能）
    initParamMap() {
      const allParams = this.projectParamConfig.paramGroups.flatMap(g => g.paramItems);
      allParams.forEach(param => {
        this.paramMap[param.paramId] = param;
        this.paramMap[param.paramCode] = param; // 支持通过paramCode查询
      });
    },

    // 2. 初始化表单数据
    initFormData() {
      this.projectParamConfig.paramGroups.forEach(group => {
        if (group.allowDynamicRows) {
          const tableKey = `group_${group.groupId}`;
          this.$set(this.formData, tableKey, [this.createEmptyTableRow(group.paramItems)]);
        } else {
          group.paramItems.forEach(param => {
            let defaultValue = param.defaultValue || '';
            if (param.isMultiMeasure) {
              defaultValue = Array(5).fill({ value: '' });
            } else if (param.dataType === 'number') {
              defaultValue = '';
            }
            this.$set(this.formData, param.paramCode, defaultValue);
          });
        }
      });
    },

    // 创建空试件行数据
    createEmptyTableRow(paramItems) {
      const row = {};
      paramItems.forEach(param => {
        let defaultValue = param.defaultValue || '';
        if (param.isMultiMeasure) {
          defaultValue = Array(5).fill({ value: '' });
        } else if (param.dataType === 'number') {
          defaultValue = '';
        }
        row[param.paramCode] = defaultValue;
      });
      return row;
    },

    // 3. 初始化表单校验规则
    initFormRules() {
      this.projectParamConfig.paramGroups.forEach(group => {
        if (group.allowDynamicRows) {
          const tableKey = `group_${group.groupId}`;
          this.$set(this.formRules, tableKey, {
            validator: (rule, value, callback) => {
              let errorMsg = '';
              value.forEach((row, idx) => {
                group.paramItems.forEach(param => {
                  if (!param.isRequired) return;
                  if (param.isMultiMeasure) {
                    const hasValid = row[param.paramCode].some(item => item.value !== '' && !isNaN(item.value));
                    if (!hasValid) {
                      errorMsg = `第${idx+1}个试件【${param.paramName}】至少填写1次测量值`;
                    }
                  } else {
                    if (row[param.paramCode] === '' || row[param.paramCode] === undefined || isNaN(row[param.paramCode])) {
                      errorMsg = `第${idx+1}个试件【${param.paramName}】为必填项且需输入有效数字`;
                    }
                  }
                });
              });
              errorMsg ? callback(new Error(errorMsg)) : callback();
            },
            trigger: 'change'
          });
        } else {
          group.paramItems.forEach(param => {
            if (param.isRequired) {
              const rules = [{ required: true, message: `${param.paramName}为必填项`, trigger: 'blur' }];
              if (param.dataType === 'number') {
                rules.push({
                  validator: (rule, value, callback) => {
                    if (value !== '' && !isNaN(value)) {
                      callback();
                    } else {
                      callback(new Error(`${param.paramName}需输入有效数字`));
                    }
                  },
                  trigger: 'blur'
                });
              }
              this.$set(this.formRules, param.paramCode, rules);
            }
          });
        }
      });
    },

    // 4. 初始化反向依赖映射（核心：通用依赖链解析）
    initReverseDependencyMap() {
      const allParams = this.projectParamConfig.paramGroups.flatMap(g => g.paramItems);
      this.reverseDependencyMap = {};

      // 遍历所有计算参数，注册反向依赖
      allParams.forEach(calcParam => {
        if (calcParam.paramType !== 'calculation' || !calcParam.dependencies?.length) return;

        // 递归收集该计算参数的所有直接/间接依赖
        const collectAllDependencies = (paramId) => {
          const depParam = this.paramMap[paramId];
          if (!depParam) return;

          // 给当前依赖参数注册反向依赖（当前计算参数依赖它）
          if (!this.reverseDependencyMap[depParam.paramId]) {
            this.reverseDependencyMap[depParam.paramId] = new Set(); // 用Set避免重复
          }
          this.reverseDependencyMap[depParam.paramId].add(calcParam);

          // 递归收集依赖参数的依赖（间接依赖）
          if (depParam.dependencies?.length) {
            depParam.dependencies.forEach(subDepId => collectAllDependencies(subDepId));
          }
        };

        // 收集当前计算参数的所有依赖
        calcParam.dependencies.forEach(depId => collectAllDependencies(depId));
      });

      // Set转数组（方便遍历）
      Object.keys(this.reverseDependencyMap).forEach(paramId => {
        this.reverseDependencyMap[paramId] = Array.from(this.reverseDependencyMap[paramId]);
      });
    },

    // 5. 获取参数标签（含单位）
    getParamLabel(param) {
      return param.unit ? `${param.paramName}(${param.unit})` : param.paramName;
    },

    // 6. 获取组件类型
    getElComponent(param) {
      if (param.isMultiMeasure) return 'multi-measure-input';
      if (param.paramType === 'calculation') return 'el-input';
      switch (param.dataType) {
        case 'text': return 'el-input';
        case 'select': return 'el-select';
        case 'textarea': return 'el-input';
        default: return 'el-input';
      }
    },

    // 7. 获取组件Props
    getComponentProps(param) {
      const props = {
        placeholder: param.isRequired ? '必填' : '选填',
        clearable: !param.isMultiMeasure && param.dataType !== 'select',
        size: 'mini'
      };

      if (param.isMultiMeasure) {
        return { ...props, precision: param.precision || 1 };
      }

      if (param.dataType === 'textarea') {
        return { ...props, type: 'textarea', rows: 4 };
      }

      return props;
    },

    // 8. 添加试件行
    addTableRow(groupId) {
      const tableKey = `group_${groupId}`;
      const group = this.projectParamConfig.paramGroups.find(g => g.groupId === groupId);
      this.formData[tableKey].push(this.createEmptyTableRow(group.paramItems));
    },

    // 9. 删除试件行
    deleteTableRow(groupId, rowIndex) {
      const tableKey = `group_${groupId}`;
      this.formData[tableKey].splice(rowIndex, 1);
      this.calcSummaryParams(); // 重新计算所有汇总参数
    },

    // 10. 数字输入失焦时格式化精度
    handleNumberBlur(e, param, target, rowIndex, groupId) {
      const { paramCode, precision = 0 } = param;
      let value = target[paramCode];
      
      if (value === '' || isNaN(value) || value === undefined) {
        target[paramCode] = '';
        return;
      }
      const formattedValue = Number(value.toFixed(precision));
      // 强制更新响应式数据
      if (target === this.formData) {
        this.$set(this.formData, paramCode, formattedValue);
        this.handleParamChange(param);
      } else {
        this.$set(target, paramCode, formattedValue);
        if (groupId && rowIndex !== undefined) {
          this.$set(this.formData[`group_${groupId}`], rowIndex, { ...target });
          this.handleParamChange(param, rowIndex, groupId);
        }
      }
    },

    // 11. 获取参数的当前值（通用：支持表格型/单值型）
    getParamValue(param, rowIndex, groupId) {
      if (groupId && rowIndex !== undefined) {
        const row = this.formData[`group_${groupId}`][rowIndex];
        return param.isMultiMeasure ? [...row[param.paramCode]] : row[param.paramCode];
      } else {
        return param.isMultiMeasure ? [...this.formData[param.paramCode]] : this.formData[param.paramCode];
      }
    },

    // 12. 更新参数值（通用：支持表格型/单值型）
    updateParamValue(param, value, rowIndex, groupId) {
      if (groupId && rowIndex !== undefined) {
        const tableKey = `group_${groupId}`;
        const row = this.formData[tableKey][rowIndex];
        this.$set(row, param.paramCode, value);
        this.$set(this.formData[tableKey], rowIndex, { ...row }); // 触发响应式
      } else {
        this.$set(this.formData, param.paramCode, value);
      }
    },

    // 13. 计算单个参数值（通用：支持任意计算参数）
    calculateParam(calcParam, rowIndex, groupId) {
      try {
        // 构建计算上下文：包含所有需要的参数值
        const context = { max: Math.max };
        const collectParamValue = (param) => {
          if (!param) return;
          // 避免循环依赖
          if (context[param.paramCode] !== undefined) return;
          
          // 添加当前参数值到上下文
          context[param.paramCode] = this.getParamValue(param, rowIndex, groupId);
          
          // 递归收集当前参数的依赖值
          if (param.dependencies?.length) {
            param.dependencies.forEach(depId => {
              collectParamValue(this.paramMap[depId]);
            });
          }
        };

        // 收集计算参数的所有依赖值
        collectParamValue(calcParam);

        // 执行计算
        const result = calcParamValue(calcParam.calculationExpr, context);
        return this.formatResult(result, calcParam.precision);
      } catch (e) {
        console.error(`计算${calcParam.paramName}失败：`, e);
        return '';
      }
    },

    // 14. 递归触发依赖当前参数的所有计算（核心：通用依赖链触发）
    triggerDependentCalculations(changedParam, rowIndex, groupId) {
      // 获取所有依赖当前参数的计算参数
      const dependentParams = this.reverseDependencyMap[changedParam.paramId] || [];
      console.log('依赖当前参数的计算参数:', dependentParams);
      dependentParams.forEach(calcParam => {
        // 计算依赖参数的新值
        const oldValue = this.getParamValue(calcParam, rowIndex, groupId);
        const newValue = this.calculateParam(calcParam, rowIndex, groupId);
        console.log(`计算${calcParam.paramName}旧值: ${oldValue} -> 新值: ${newValue}`);
        // 只有值变化时才更新（避免死循环）
        if (newValue !== oldValue) {
          this.updateParamValue(calcParam, newValue, rowIndex, groupId);
          // 递归触发依赖当前计算参数的下一级计算
          this.triggerDependentCalculations(calcParam, rowIndex, groupId);
        }
      });

      // 如果是汇总参数的依赖变化，重新计算汇总
      if (changedParam.paramCode === 'density') {
        this.calcSummaryParams();
      }
    },

    // 15. 参数变化统一处理入口（通用：支持任意参数）
    handleParamChange(param, rowIndex, groupId) {
    
      // 第一步：处理参数自身的值格式化（多次测量/数字类型）
      if (groupId && rowIndex !== undefined) {
        const row = this.formData[`group_${groupId}`][rowIndex];
        if (param.isMultiMeasure) {
          // 过滤多次测量的无效值
          const formattedValue = row[param.paramCode].map(item => ({
            value: item.value !== '' && !isNaN(item.value) ? Number(item.value) : ''
          }));
          this.updateParamValue(param, formattedValue, rowIndex, groupId);
        } else if (param.dataType === 'number') {
          // 过滤数字类型的无效值
          const value = row[param.paramCode];
          const formattedValue = value === '' || isNaN(value) ? '' : Number(value);
          this.updateParamValue(param, formattedValue, rowIndex, groupId);
        }
      } else if (param.dataType === 'number' && !param.isMultiMeasure) {
        const value = this.formData[param.paramCode];
        const formattedValue = value === '' || isNaN(value) ? '' : Number(value);
        this.updateParamValue(param, formattedValue);
      }
      // 第二步：触发所有依赖当前参数的计算（递归穿透）
      this.triggerDependentCalculations(param, rowIndex, groupId);
    },

    // 16. 计算所有汇总参数（通用：支持多个汇总参数）
    calcSummaryParams() {
      const summaryGroup = this.projectParamConfig.paramGroups.find(g => g.groupId === 'GRP002');
      if (!summaryGroup) return;

      summaryGroup.paramItems.forEach(param => {
        if (param.paramType === 'calculation') {
          const oldValue = this.getParamValue(param);
          const newValue = this.calculateParam(param);
          if (newValue !== oldValue) {
            this.updateParamValue(param, newValue);
          }
        }
      });
    },

    // 工具：格式化计算结果（处理浮点数精度）
    formatResult(result, precision = 0) {
      if (result === '' || isNaN(result) || result === undefined || result === null) return '';
      // 处理浮点数精度问题（如 0.1+0.2=0.30000000000000004）
      return precision > 0 
        ? Number(parseFloat(result).toFixed(precision)) 
        : Number(parseFloat(result).toFixed(0));
    },

    // 17. 表单提交
    submitForm() {
      this.$refs.experimentForm.validate((valid) => {
        if (valid) {
          const submitData = {
            projectId: this.projectParamConfig.projectId,
            formData: JSON.parse(JSON.stringify(this.formData))
          };
          this.$emit('submit', submitData);
        } else {
          this.$message.error('请完善必填项并修正输入错误！');
        }
      });
    },

    // 18. 表单重置
    resetForm() {
      this.$refs.experimentForm.resetFields();
      this.initFormData();
      this.$message.info('表单已重置！');
    }
  }
};
</script>

<style scoped>
.experiment-form {
  padding: 10px;
}
.form-title {
  font-size: 16px;
  font-weight: 700;
  color: #333;
  margin-bottom: 20px;
  padding-bottom: 10px;
  border-bottom: 1px solid #eee;
}
.param-group {
  margin-bottom: 30px;
}
.group-title {
  font-size: 14px;
  font-weight: 600;
  color: #666;
  margin-bottom: 12px;
  display: flex;
  align-items: center;
}
.title-icon {
  width: 4px;
  height: 14px;
  background: #409eff;
  margin-right: 8px;
  border-radius: 2px;
}
.dynamic-table {
  margin-bottom: 12px;
}
.add-row-btn {
  color: #409eff;
  margin-bottom: 10px;
}
.delete-row-btn {
  color: #f56c6c;
}
.single-value-group {
  background: #fafafa;
  padding: 15px;
  border-radius: 8px;
}
.form-item-col {
  margin-bottom: 15px;
}
.form-actions {
  margin-top: 30px;
  display: flex;
  gap: 10px;
}
/* 适配数字输入框样式，与多次测量组件对齐 */
.el-input--mini.el-input--number .el-input__inner {
  text-align: center;
}
/* 计算参数输入框样式优化：placeholder 灰色更明显 */
.el-input.is-disabled input[placeholder="自动计算"] {
  color: #999 !important;
  font-style: italic;
}
</style>